﻿using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Cms.Domain.Authentication;
using Cms.Web.Framework.Infrastructure;

namespace Cms.Web.Framework.Controls
{
    public class DetailTemplate : MasterPage
    {
        private readonly RequestDetails _details;
        private readonly DetailTemplateContentWrapper _wrapper;

        public DetailTemplate()
        {
            _details = (RequestDetails)HttpContext.Current.Items["RequestDetails"];
            IList<string> pageAreas = new List<string>();
            if (_details.MasterTemplate != null && _details.MasterTemplate.ID > 0)
            {
                MasterPageFile = "~/__System/MasterTemplates/" + _details.MasterTemplate.ID + ".Master";
                pageAreas = _details.MasterTemplate.PageAreas;
            }
            else
            {
                AuthenticatedUser user = Conversion.ToAuthenticatedUser(Context.User.Identity.Name);
                MasterPageFile = "~/Admin/Resources/Temp/" + user.AdministratorID + "/TestMasterTemplate.master";
            }
            
            // Dynamically create a surrogate Content control. It will then be populated using AddParsedSubObject
            // This way, we don´t have to begin every DetailTemplate file with:
            // <asp:content id="xxx" runat="server" contentplaceholderid="DetailTemplatePlaceHolder">
            _wrapper = new DetailTemplateContentWrapper();
            AddContentTemplate("DetailTemplatePlaceHolder", _wrapper);
            if (_details.Page == null || !(_details.Page is Cms.Domain.ApplicationPage))
            {
                return;
            }
            foreach (string area in pageAreas)
            {
                var pageAreaWrapper = new PageContentWrapper();
                pageAreaWrapper.ID = area + "PlaceHolder";
                ContentPlaceHolder pageAreaContent = new ContentPlaceHolder();
                pageAreaContent.ID = area;
                pageAreaWrapper.Controls.Add(pageAreaContent);
                AddContentTemplate(area, pageAreaWrapper);
                this.ContentPlaceHolders.Add(area.ToLower());
            }
        }

        public RequestDetails RequestDetails
        {
            get { return _details; }
        }
        
        protected override void AddParsedSubObject(object obj)
        {
            // Hijack all child controls and add them to the Content control
            if (obj is Control)
                _wrapper.Controls.Add((Control)obj);
            if (obj is DetailTemplateContentWrapper || obj is Content)
                _details.ContentPlaceHolders.Add((Content)obj);
        }
        
        // Custom class for emulating a System.Web.UI.WebControls.Content control
        #region Nested type: DetailTemplateContentWrapper

        private class DetailTemplateContentWrapper : Control, ITemplate
        {
            #region ITemplate Members

            public void InstantiateIn(Control container)
            {
                while (Controls.Count > 0)
                {
                    container.Controls.Add(Controls[0]);

                    // There is no need to call this.RemoveAt[0], the controls are automatically 
                    // removed from this.Controls when they are added to container.Controls
                }
            }

            #endregion
        }

        private class PageContentWrapper : Control, ITemplate
        {
            #region ITemplate Members

            public void InstantiateIn(Control container)
            {
                while (Controls.Count > 0)
                {
                    container.Controls.Add(Controls[0]);
                }
            }

            #endregion
        }

        #endregion
    }
}